<?php

namespace app\common\model\xilujob;

use think\Db;
use think\Exception;
use think\Hook;
use think\Log;
use think\Model;
use think\Validate;
use function fast\array_get;

class JobInterview extends Model
{
    protected $name = 'xilujob_job_interview';
    protected $autoWriteTimestamp = 'int';

    protected $createTime = 'createtime';
    protected $updateTime = 'updatetime';

    const STATUS_INTERVIEW_SENT = 0; //面试邀请(等待用户回应)
    const STATUS_INTERVIEW_REJECTED = 1; //拒绝面试邀请(完结)
    const STATUS_INTERVIEW_ACCEPTED = 2; //同意面试邀请
    const STATUS_INTERVIEW_FAILED = 3; //面试失败(完结)
    const STATUS_INTERVIEW_PASSED = 4; //面试成功(完结)


    const STATUS_TRANSITION = [
        self::STATUS_INTERVIEW_SENT => [self::STATUS_INTERVIEW_REJECTED, self::STATUS_INTERVIEW_ACCEPTED],
        self::STATUS_INTERVIEW_REJECTED => [],
        self::STATUS_INTERVIEW_ACCEPTED => [self::STATUS_INTERVIEW_FAILED, self::STATUS_INTERVIEW_PASSED],
        self::STATUS_INTERVIEW_FAILED => [],
        self::STATUS_INTERVIEW_PASSED => [],
    ];

//    public function user() {
//        return $this->belongsTo('User','user_id','id',[],'INNER')->setEagerlyType(0);
//    }

    public function resume() {
        return $this->belongsTo('Resume','resume_id','id',[],'INNER')->setEagerlyType(0);
    }

    public function job() {
        return $this->belongsTo('Job','job_id','id',[],'INNER')->setEagerlyType(0);
    }

    public function enterpriseinfo() {
        return $this->belongsTo('EnterpriseInfo','company_id','company_id')->setEagerlyType(0);
    }

//    public function feedback() {
//        return $this->hasOne('ApplyFeedback', 'apply_id', 'id', [], 'LEFT');
//    }

    /**
     * 邀请面试
     * @param array $params
     * @return
     */
    public static function createInterview($params) {
        $validator = Validate::make([
            'user_id|用户' => ['require'],
            'resume_id|简历' => ['require'],
            'company_id|公司' => ['require'],
            'job_id|职位' => ['require','job_valid'],
            'interview_time|面试时间' => ['require','dateFormat:Y-m-d H:i'],
            'address|地址' => ['require','length:1,50'],
            'contact|联系人' => ['require','length:1,20'],
            'contact_phone|联系电话' => ['require','regex:/^\d{11}$/'],
            'notice|备注' => ['length:0,255'],
            'send_message' => ['in:0,1']
        ]);
        $validator->extend('job_valid', function($value) use($params) {
            $job = Job::get($value);
            if(!$job) {
                throw new Exception('职位已被删除');
            }
            // 邀请面试不需要职位已发布
            if(/*$job->status!=Job::STATUS_ENABLED ||*/ $job->publisher_id!=$params['company_id'])
                throw new Exception('职位选择错误');

            return true;
        });
        if(!$validator->check($params)) {
            throw new Exception($validator->getError());
        }
        if(EnterpriseInfo::getAvailableNum($params['company_id'],'interview') <= 0) {
            throw new Exception("您购买的面试邀请数已用尽，请前往购买");
        }
        Db::startTrans();
        try {
            //邀请简历也不能看联系方式
            //$result = ResumeActionLog::record($params['company_id'], $params['user_id'], $params['resume_id']);
            if($applyId = array_get($params,'apply_id')) {
                $apply = JobApply::get($applyId);
                if(!$apply) {
                    throw new Exception(__('no record'));
                }
                if($params['user_id'] != $apply->user_id || $params['company_id'] != $apply->company_id) {
                    throw new Exception(__('no record'));
                }
//            if($apply->status!=JobApply::STATUS_APPLY_SENT) {
//                throw new Exception('已经邀请过面试');
//            }
            }
//        if($params['user_id']==$params['company_id']) {
//            throw new Exception('无法对自己操作');
//        }

            $interview = new JobInterview();
            $params = array_intersect_key($params, array_flip(['user_id','resume_id','company_id','job_id','interview_time', 'address','contact','contact_phone','contact_email','notice','send_message']));
            $params['status'] = self::STATUS_INTERVIEW_SENT;
            $params['interview_time'] = strtotime($params['interview_time']);
            $ret = $interview->save($params);
            if($ret===false) {
                throw new Exception($interview->getError());
            }
            if(isset($apply)) {
                //更改apply状态为已邀请面试
                $apply->save([
                    'status'=>JobApply::STATUS_INTERVIEW_SENT,'interview_id'=>$interview->id,
                    'accepttime' => time()
                ]);
            }else {
                //将该个人用户对此职位的未处理投递改为已邀请面试
                $result = JobApply::where('user_id', $params['user_id'])->where('job_id', $params['job_id'])
                    ->where('status', JobApply::STATUS_APPLY_SENT)
                    ->update(['status'=>JobApply::STATUS_INTERVIEW_SENT,'interview_id'=>$interview->id,
                        'accepttime' => time()]);
            }

            if(isset($apply)) {
                //更新投递面试安排数
                CompanyStatistics::where('company_id', $params['company_id'])->update(['apply_invite_count'=>Db::raw('apply_invite_count+1'),'interview_invite_count'=>Db::raw('interview_invite_count+1')]);
            }else {
                //更新企业面试邀请数
                CompanyStatistics::where('company_id', $params['company_id'])->update(['interview_invite_count'=>Db::raw('interview_invite_count+1')]);
            }
            //更新用户 被邀请面试数
            $inviteCount = JobInterview::where('user_id', $params['user_id'])->count();
            Member::where('id', $params['user_id'])->update(['interview_invite_count'=>$inviteCount]);
            //减少次数
            EnterpriseInfo::where(['company_id'=>$params['company_id']])->update(['interview_num'=>Db::raw('interview_num-1')]);
            Hook::listen('xilujob_interview_sent', $interview);
            Db::commit();
            return $interview;
        }catch (\Exception $e) {
            Log::error($e->getMessage()."\n".$e->getTraceAsString());
            Db::rollback();
            throw $e;
        }
    }

    /**
     * 是否正处于面试状态
     * @param $userId
     * @param $companyId
     * @return bool
     */
    public static function isInterviewing($userId, $companyId) {
        if(!$userId || !$companyId) {
            return false;
        }
        $isInterviewing = static::where('user_id', $userId)->where('company_id',$companyId)
            ->whereIn('status',[self::STATUS_INTERVIEW_SENT,self::STATUS_INTERVIEW_ACCEPTED])
            ->count();
        return $isInterviewing>0;
    }

    /**
     * 改变状态
     * @param JobInterview|int $interview
     * @param int $status
     * @param string|null $reason
     * @return array|null|string|static
     */
    public static function transitStatus($interview, $status) {
        if(!$interview instanceof JobInterview) {
            $interview = JobInterview::get($interview);
        }
        if(!$interview) {
            throw new Exception('没有面试可以处理');
        }
        $transition = self::STATUS_TRANSITION[$interview->status];
        if(!in_array($status, $transition)) {
            throw new Exception('状态变更失败');
        }
        $data = ['status'=>$status];
        switch ($status) {
            case self::STATUS_INTERVIEW_REJECTED:
                $data['rejecttime'] = time();
                $eventTag = 'xilujob_interview_rejected';
                break;
            case self::STATUS_INTERVIEW_ACCEPTED:
                $data['accepttime'] = time();
                $eventTag = 'xilujob_interview_accepted';
                break;
            case self::STATUS_INTERVIEW_FAILED:
                $data['failtime'] = time();
                $eventTag = 'xilujob_interview_failed';
                break;
            case self::STATUS_INTERVIEW_PASSED:
                $data['passtime'] = time();
                $eventTag = 'xilujob_interview_passed';
                break;
        }
        Db::startTrans();
        if($interview->save($data)===false) {
            Db::rollback();
            return $interview->getError();
        }
        Hook::listen($eventTag, $interview);
        Db::commit();
        return $interview;
    }


}
